<?php


namespace App\Services;


use Qiniu\Auth;
use Illuminate\Support\Facades\Cache;
use App\Services\VideoService;
use App\Utils\Code;
use Qiniu\Processing\PersistentFop;

class QiniuService extends BaseService
{
    protected $auth;
    protected $bucket;

    public function __construct()
    {
        $accessKey = config('app.qiniu.access_key');
        $secretKey = config('app.qiniu.secret_key');
        $this->auth = new Auth($accessKey, $secretKey);
        $this->bucket = config('app.qiniu.bucket');
    }

    /**
     * 创建数据
     * @param array $params
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function getToken(array $params) {
        if (isset($params['refresh_cache']) && $params['refresh_cache'] == 1) {
            Cache::forget('qiniu_upload_token');
        }
        return Cache::remember('qiniu_upload_token', 86400, function () {
            $policy = array(
                'persistentOps' => 'avthumb/mp4',
                'fsizeLimit' => 1024 * 1024 * 1024, // 文件大小限制，这里设置为1GB
            );
            return $this->auth->uploadToken($this->bucket, null, 86500, $policy);
        });
    }
    
     /**
     * 触发视频分段处理
     * @param string $key 七牛云文件key（文件名）
     * @param int $segmentTime 分段时长（单位：秒）
     * @param string $pipeline 处理队列名称（默认使用公共队列）
     * @param string|null $callbackUrl 回调URL
     * @return array 持久化处理结果
     */
    public function segmentVideo(
        string $key,
        int $segmentTime = 10,
        string $pipeline = 'default.sys',
        ?string $callbackUrl = null
    ) {
        // 构建处理指令（HLS 分片）
        $fops = "segment/mp4/segtime/{$segmentTime}/savePattern/" . $this->urlSafeBase64Encode("$(keybase)$(count).mp4");
        // 初始化持久化处理对象
        $persistentFop = new PersistentFop($this->auth);
        // 执行处理
        list($ret, $err) = $persistentFop->execute(
            $this->bucket,
            $key,
            [$fops],
            $pipeline,
            $callbackUrl
        );
        // 结果处理
        if ($err !== null) {
            throw new \Exception("处理失败: " . json_encode($err));
        }
        return $ret;
    }

    private function urlSafeBase64Encode(string $data): string
    {
        return str_replace(['+', '/'], ['-', '_'], base64_encode($data));
    }

    /**
     * 回调接口
     */
    public function callback(array $params) {
        try {
            $kodoFile = $params['ops'][1]['fop']['result']['kodo_file'];
            (new VideoService())->store([
                'name' => $kodoFile['key'],
                'path' => $kodoFile['key']
            ]);
        } catch (\Exception $e) {
            Code::exceptionLog($e);
        }
    }
    
    /**
     * 回调接口
     */
    public function callbackImage($params) {
        try {
            // {
            //     "Id":"663c89a91cbe57fc75302fc0",
            //     "Subject":"Qiniu KODO Notification",
            //     "Timestamp":"2024-05-09T16:30:33+08:00",
            //     "Message" : "{
            //         \"name\":\"image_upload\",
            //         \"event\":\"put\",
            //         \"time\":1715243433078817808,
            //         \"reqid\":\"-tkAAABfL2_QxM0X\",
            //         \"access_key\":\"E0plcxsBEGoim-sfrlbkYKiF2jfT_cQaOgV3HqOh\",
            //         \"user_id\":\"qrn:iam::1001970673381:root\",
            //         \"source_ip\":\"36.100.192.14\",
            //         \"bucket\":\"videogen\",
            //         \"key\":\"image\/background.png\",
            //         \"fsize\":1146511,
            //         \"hash\":\"Fo7dmd4-Y-8fQYjqiw9qgtZIPrKe\",
            //         \"ftype\":0,
            //         \"mimetype\":\"image\/png\",
            //         \"itbl\":522395736,
            //         \"region\":\"z2\",
            //         \"s3etag\":\"e47280ac8e3c6bbf99093badf82d36a9\"
            //     }"
            // }
            Code::log($params['Message']);
            $msg = json_decode($params['Message'], true);
            $key = $msg['key'];
            (new VideoService())->store([
                'name' => $key,
                'path' => $key,
                'type' => 2
            ]);
        } catch (\Exception $e) {
            Code::exceptionLog($e);
        }
    }
}
